﻿using System;
using System.Drawing;
using System.Linq;
using CommonBehaviors.Actions;
using Altarboy;
using Styx;
using Styx.Helpers;
using Styx.Logic.Combat;
using Styx.Logic.Inventory;
using Styx.Logic.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;
using Action = TreeSharp.Action;

namespace Altarboy
{
    class PriestComposites
    {

        #region Delegates
        public delegate bool SimpleBoolReturnDelegate(object context);
        public delegate WoWUnit UnitSelectionDelegate(object context);
        #endregion

        // Current Player   
        public static LocalPlayer Me { get { return StyxWoW.Me; } }

        public static Composite CastMindSear(SimpleBoolReturnDelegate extra)
        {

            //Todo - Should add logic to check for CC'ed targets within Mindsear Range.
            return new Decorator(
             ret => extra(ret),
             new Sequence(
                //new Action(ret => Navigator.PlayerMover.MoveStop()), | Beyond annoying.                           
                        new Action(ret => TargetManager.ActiveTarget.Face()),
                        new Action(ret => CastManager.CastSpell("Mind Sear", TargetManager.ActiveTarget))
              )
            );
        }

        public static Composite BuffFortitude()
        {
            return new Decorator(
               ret => (AltarboySettings.Instance.BuffFortitude && PartyManager.NearbyGroupMembers.Any(CanCastFortitudeOn) && CastManager.CanCast("Power Word: Fortitude", Me)),
                   new Action(delegate { CastManager.CastSpell("Power Word: Fortitude", Me); })
            );
        }


        public static Composite BuffShadowProtection()
        {
            return new Decorator(
               ret => (AltarboySettings.Instance.BuffShadowProtection && CastManager.CanCast("Shadow Protection", Me) &&
                   PartyManager.NearbyGroupMembers.Any(CanCastShadowProtection)),
                  new Action(delegate { CastManager.CastSpell("Shadow Protection", Me); })
            );
        }

        //credits singular
        public static bool CanCastFortitudeOn(WoWUnit unit)
        {
            return !AuraManager.UnitHasAura(unit, "Power Word: Fortitude");
        }

        public static bool CanCastShadowProtection(WoWUnit unit)
        {
            return !AuraManager.UnitHasAura(unit, "Shadow Protection");
        }

        public static bool CanPowerWordShield(WoWUnit target)
        {
            return !AuraManager.HasAuraStacks("Weakened Soul", 0, target) && CastManager.CanCast("Power Word: Shield", target);
        }

        public static Composite CommonPriestBuffs()
        {
            return new Decorator(ret => !CastManager.IsHymning(),
               new PrioritySelector(
                  HandleFalling(),
                  BuffFortitude(),
                  BuffShadowProtection(),
                  AltarboyComposites.BuffSelf("Shadowform", ret => (AltarboySettings.Instance.UseShadowForm)),
                  AltarboyComposites.BuffSelf("Vampiric Embrace", ret => (AltarboySettings.Instance.UseVampiricEmbrace)),
                  AltarboyComposites.BuffSelf("Inner Fire", ret => (AltarboySettings.Instance.UseInnerFire)),
                  AltarboyComposites.BuffSelf("Inner Will", ret => (AltarboySettings.Instance.UseInnerWill))
              ));
        }

        //We should add a glyph check here. If someone doesn't have the levitate glphy this will kill them.
        public static Composite HandleFalling()
        {
            return new Decorator(ret => AltarboySettings.Instance.LevitateWhileFalling && Me.IsFalling,

                new PrioritySelector(

                    //Do I already have levitate
                    new Decorator(ret => AuraManager.HasMyAura("Levitate", Me),
                        new Sequence(
                            new WaitContinue(TimeSpan.FromSeconds(2), ret => AuraManager.HasMyAura("Levitate", Me), new ActionAlwaysSucceed()),
                            new Action(delegate { Lua.DoString("CancelUnitBuff(\"player\", \"Levitate\")"); })
                        )
                    ),

                    //I don't have levitate.
                    new Decorator(ret => !AuraManager.HasMyAura("Levitate", Me),
                        new Sequence(
                            new WaitContinue(TimeSpan.FromSeconds(4), ret => Me.IsFalling, new ActionAlwaysSucceed()),
                            new Decorator(ret => Me.IsFalling, AltarboyComposites.BuffSelf("Levitate", ret => (Me.IsFalling)))
                        )
                   )
                )
           );
        }

        #region Healing

        public static Composite HealSelf()
        {
            return new PrioritySelector(
                new Decorator(ret => Me.HealthPercent <= 20, AltarboyComposites.CastSpell("Flash Heal", ret => (true), Me)),
                new Decorator(ret => Me.HealthPercent <= 30, AltarboyComposites.CastSpell("Penance", ret => (true), Me)),
                new Decorator(
                    ret => AuraManager.GetAuraTimeLeft("Renew", Me, true).TotalSeconds <= 1 && Me.HealthPercent <= 80,
                    AltarboyComposites.CastSpell("Renew", ret => (true), Me)
                ),

                new Decorator(
                    ret => CanPowerWordShield(Me) && Me.HealthPercent <= 90,
                    AltarboyComposites.CastSpell("Power Word: Shield", ret => (true), Me)
                )
            );

        }



        // Credits Singular
        //public static Composite CreateWaitForCastWithCancel(int minHealth)
        //{
        //    return new PrioritySelector(
        //        new Decorator(
        //            ret => Me.IsCasting,
        //            new PrioritySelector(
        //                new Decorator(
        //                    ret => Me.CurrentTarget == null
        //                        || (Me.CurrentTarget is WoWPlayer && Me.IsHorde != ((WoWPlayer)Me.CurrentTarget).IsHorde)
        //                        || !Me.CurrentTarget.IsFriendly
        //                        || Me.CurrentTarget.HealthPercent < minHealth
        //                        || Me.CastingSpell == null
        //                        || Me.CastingSpell.SpellEffect1 == null
        //                        || Me.CastingSpell.SpellEffect1.EffectType != WoWSpellEffectType.Heal,
        //                    new ActionAlwaysSucceed()),
        //                new Action(delegate
        //                {
        //                    string spellName = Me.CastingSpell.Name;
        //                    double healthPct = Me.CurrentTarget.HealthPercent;
        //                    SpellManager.StopCasting();
        //                    Logging.Write(Color.Orange, "Cancelled {0} on {1} at {2:F0}%", spellName, Me.CurrentTarget.Name, healthPct);
        //                }))
        //            )
        //        );
        //}

        #endregion


    }
}
